package com.travel.travelServer.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.travel.travelServer.entity.Permission;
import com.travel.travelServer.entity.RolePermission;
import com.travel.travelServer.mapper.PermissionMapper;
import com.travel.travelServer.mapper.RolePermissionMapper;
import com.travel.travelServer.service.PermissionService;
import com.travel.travelServer.utils.BaseService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * (Permission)表服务实现类
 *
 * @author makejava
 * @since 2023-10-24 16:42:30
 */
@Service
public class PermissionServiceImpl extends BaseService<PermissionMapper, Permission> implements PermissionService {

    @Resource
    private PermissionMapper permissionDao;

    @Resource
    private RolePermissionMapper rolePermissionDao;

    @Override
    public List<Permission> getByLevel(Integer level) {
        QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>();
        permissionQueryWrapper.lambda().eq(Permission::getLevel, level - 1);
        permissionQueryWrapper.lambda().eq(Permission::getStatus, 0);
        return permissionDao.selectList(permissionQueryWrapper);
    }

    @Override
    public Page<Permission> pageByPermission(Page<Permission> page, Map<String, Object> conditions) {
        QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>();
        permissionQueryWrapper.like(Objects.nonNull(conditions.get("name")) && !conditions.get("name").equals("")
                ,"name", conditions.get("name"));
        permissionQueryWrapper.like(Objects.nonNull(conditions.get("url")) && !conditions.get("url").equals("")
                ,"url", conditions.get("url"));
        permissionQueryWrapper.like(Objects.nonNull(conditions.get("permissionValue")) && !conditions.get("permissionValue").equals("")
                ,"permission_value", conditions.get("permissionValue"));
        permissionQueryWrapper.lambda().eq(Permission::getLevel, 1);
        Page<Permission> dbPage = super.page(page, permissionQueryWrapper);
        List<Permission> permissionList = getChildrenList(dbPage.getRecords());
        return page.setRecords(permissionList);
    }

    @Override
    public Permission getPermissionById(Long id) {
        return super.getById(id);
    }

    @Override
    public Boolean savePermission(Permission permission) {
        return super.save(permission);
    }

    @Override
    public Boolean updatePermissionById(Permission permission) {
        return super.updateById(permission);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removePermissionById(Long id) {
        return deleteSonPermission(id);
    }

    private Boolean deleteSonPermission(Long id){
        boolean a = super.removeById(id);
        QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>();
        permissionQueryWrapper.lambda().eq(Permission::getPid, id);
        List<Permission> list = super.list(permissionQueryWrapper);
        if (list.size() > 0){
            list.stream().forEach(permission -> {
                this.deleteSonPermission(permission.getId());
            });
        }
        return a;
    }

    @Override
    public Boolean removePermissionByIds(List<Long> idList) {
        return super.removeByIds(idList);
    }

    @Override
    public List<Map<String, Object>> getPermissionTreeList() {
        QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>();
        permissionQueryWrapper.lambda().eq(Permission::getLevel, 1);
        List<Permission> permissions = permissionDao.selectList(permissionQueryWrapper);
        return getTreeList(permissions);
    }

    @Override
    public List<Permission> getByRoleId(Long id) {
        QueryWrapper<RolePermission> rolePermissionQueryWrapper = new QueryWrapper<>();
        rolePermissionQueryWrapper.lambda().eq(RolePermission::getRoleId, id);
        List<RolePermission> rolePermissions = rolePermissionDao.selectList(rolePermissionQueryWrapper);
        List<Permission> permissions = null;
        Set<Permission> removePermissions = new HashSet<>();
        if (rolePermissions.size() > 0){
            List<Long> permissionIds = rolePermissions.stream().map(
                    rolePermission -> rolePermission.getPermissionId()).collect(Collectors.toList());
            permissions = permissionDao.selectBatchIds(permissionIds);
            for (Permission wPermission : permissions) {
                for (Permission lPermission : permissions) {
                    if (wPermission.getId().equals(lPermission.getPid())){
                        removePermissions.add(wPermission);
                        continue;
                    }
                }
            }
        }
        if (removePermissions.size() > 0){
            permissions.removeAll(removePermissions);
        }
        return permissions;
    }

    private List<Permission> getChildrenList(List<Permission> permissionList){
        permissionList.stream().forEach(
            permission -> {
                QueryWrapper<Permission> sonPermissionQueryWrapper = new QueryWrapper<>();
                sonPermissionQueryWrapper.lambda().eq(Permission::getPid, permission.getId());
                List<Permission> permissions = permissionDao.selectList(sonPermissionQueryWrapper);
                if (permissions.size() > 0){
                    permission.setSonPermissionList(permissions);
                    getChildrenList(permissions);
                }
            });
        return permissionList;
    }

    private List<Map<String, Object>> getTreeList(List<Permission> permissionList){
        List<Map<String, Object>> mapList = new ArrayList<>();
        permissionList.stream().forEach(
                permission -> {
                    HashMap<String, Object> map = new HashMap<>();
                    map.put("id", permission.getId().toString());
                    map.put("label", permission.getName());
                    QueryWrapper<Permission> sonPermissionQueryWrapper = new QueryWrapper<>();
                    sonPermissionQueryWrapper.lambda().eq(Permission::getPid, permission.getId());
                    List<Permission> permissions = permissionDao.selectList(sonPermissionQueryWrapper);
                    if (permissions.size() > 0){
                        map.put("children", getTreeList(permissions));
                    }
                    mapList.add(map);
                });
        return mapList;
    }
}

